package dao.impl;

import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Vector;
import boerrors.TechnicienExistantException;
import boerrors.TechnicienInexistantException;
import dao.TechnicienDao;
import dao.dto.AdresseDto;
import dao.dto.CodePostalDto;
import dao.dto.EmployeDto;
import dao.dto.ZoneDto;
import dao.dto.RoleDto;
import dao.dto.TechnicienDto;

public class TechnicienDaoImpl extends TechnicienDao {
        private static TechnicienDao _instance = null;
        private CallableStatement _callableStatement = null;
        private SQLConnection _connection = new SQLConnection();
        
        //Constructeur du singleton
	public static TechnicienDao getInstance(){
		if(_instance == null)
			_instance = new TechnicienDaoImpl();
		return _instance;
	}
            
        
        //Methodes
        @Override
        public void enregistrer(TechnicienDto technicien) throws TechnicienExistantException {
            try {
                    //query
                    _callableStatement = _connection.getConnection().prepareCall("{call sp_RHTechnicienInsert(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}");
                   
                    //parameter
                    _callableStatement.setInt("idRHMatricule",technicien.getMatricule());
                    _callableStatement.setString("nom",technicien.getNom());
                    _callableStatement.setString("prenom",technicien.getPrenom());
                    _callableStatement.setString("rue",technicien.getAdresse().getRue());
                    _callableStatement.setString("numero",technicien.getAdresse().getNumero());
                    _callableStatement.setInt("codePostalFK",technicien.getAdresse().getCodePostal().getIdCodePostal());
                    _callableStatement.setString("telephone",technicien.getTelephone());
                    _callableStatement.setString("email",technicien.getEmail());
                    _callableStatement.setString("fonction",technicien.getFonction());                        
                    _callableStatement.setString("password",technicien.getPassword());
                    _callableStatement.setBoolean("gestionClient",technicien.getRole().getGestionClient());
                    _callableStatement.setBoolean("gestionDirection",technicien.getRole().getGestionDirection());
                    _callableStatement.setBoolean("gestionIntervention",technicien.getRole().getGestionIntervention());
                    _callableStatement.setBoolean("gestionOnSite",technicien.getRole().getGestionOnSite());
                    _callableStatement.setBoolean("gestionPlanning",technicien.getRole().getGestionPlanning());
                    _callableStatement.setBoolean("gestionSysteme",technicien.getRole().getGestionSysteme());
                    _callableStatement.setInt("zoneFK",technicien.getZone().getIdZone());
                    //execute
                    _callableStatement.executeUpdate();    
        } catch(SQLException e) {
            if (e.getMessage().equals("547")) {
                throw new TechnicienExistantException("Code postal/Adresse/Role/Zone Incorrect (FK)",e);
            } else if (e.getMessage().equals("515")) {
                throw new TechnicienExistantException("Non autorisé champs vide",e);
            } else if (e.getMessage().equals("2627")) {
                throw new TechnicienExistantException("Le matricule existe déjà",e);
            } else if (e.getMessage().equals("50001")) {
                throw new TechnicienExistantException("Un technicien doit avoir le droit gestionOnsite",e);
            } else  throw new TechnicienExistantException(e);
        } catch(Exception e){
            throw new TechnicienExistantException(e);
        } finally {
                if (_callableStatement != null) try { _callableStatement.close(); } catch(Exception e) {throw new TechnicienExistantException(e);}
                _connection.deconnecter();
        }
    }
        
    @Override
    public void modifier(TechnicienDto technicien) throws TechnicienInexistantException {
            try {
                    //query
                    _callableStatement = _connection.getConnection().prepareCall("{call sp_RHTechnicienUpdate(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}");
                    //parameter
                    
                    _callableStatement.setInt("idRHMatricule",technicien.getMatricule());
                    _callableStatement.setString("nom",technicien.getNom());
                    _callableStatement.setString("prenom",technicien.getPrenom());
                    _callableStatement.setString("telephone",technicien.getTelephone());
                    _callableStatement.setString("email",technicien.getEmail());
                    //_callableStatement.setInt("idAdresse",technicien.getAdresse().getIdAdresse());
                    _callableStatement.setString("rue",technicien.getAdresse().getRue());
                    _callableStatement.setString("numero",technicien.getAdresse().getNumero());
                    _callableStatement.setInt("codePostalFK",technicien.getAdresse().getCodePostal().getIdCodePostal());
                    _callableStatement.setString("fonction",technicien.getFonction());                        
                    _callableStatement.setString("password",technicien.getPassword());
                    //_callableStatement.setInt("idRoles",technicien.getRole().getIdRole());
                    _callableStatement.setBoolean("gestionClient",technicien.getRole().getGestionClient());
                    _callableStatement.setBoolean("gestionDirection",technicien.getRole().getGestionDirection());
                    _callableStatement.setBoolean("gestionIntervention",technicien.getRole().getGestionIntervention());
                    _callableStatement.setBoolean("gestionOnSite",technicien.getRole().getGestionOnSite());
                    _callableStatement.setBoolean("gestionPlanning",technicien.getRole().getGestionPlanning());
                    _callableStatement.setBoolean("gestionSysteme",technicien.getRole().getGestionSysteme());
                    _callableStatement.setInt("zoneFK",technicien.getZone().getIdZone());
                
                    //execute
                    _callableStatement.executeUpdate();    

        } catch(SQLException e) {
            if (e.getMessage().equals("547")) {
                throw new TechnicienInexistantException("Code postal/Adresse/Role/Zone Incorrect",e);
            } else if (e.getMessage().equals("515")) {
                throw new TechnicienInexistantException("Non autorisé champs vide",e);
            } else if (e.getMessage().equals("50001")) {
                    throw new TechnicienInexistantException("Le technicien n'existe pas",e);
            } else if (e.getMessage().equals("50002")) {
                    throw new TechnicienInexistantException("L'adresse n'a pas été trouvé",e);
            } else if (e.getMessage().equals("50003")) {
                    throw new TechnicienInexistantException("Le Rôle n'a pas été trouvé ",e);
            } else if (e.getMessage().equals("50004")) {
                throw new TechnicienInexistantException("Un technicien doit avoir le droit gestionOnsite",e);
            } else  throw new TechnicienInexistantException(e);
        } catch(Exception e){
            throw new TechnicienInexistantException(e);
        } finally {
                if (_callableStatement != null) try { _callableStatement.close(); } catch(Exception e) {throw new TechnicienInexistantException(e);}
                _connection.deconnecter();
        }
    }    
    
    @Override
    public void modifierEmployeToTechnicien(TechnicienDto technicien) throws TechnicienInexistantException {
            try {
                    //query
                    _callableStatement = _connection.getConnection().prepareCall("{call sp_RHEmployeToTechnicienUpdate(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}");
                    //parameter
                    
                    _callableStatement.setInt("idRHMatricule",technicien.getMatricule());
                    _callableStatement.setString("nom",technicien.getNom());
                    _callableStatement.setString("prenom",technicien.getPrenom());
                    _callableStatement.setString("telephone",technicien.getTelephone());
                    _callableStatement.setString("email",technicien.getEmail());
                    //_callableStatement.setInt("idAdresse",technicien.getAdresse().getIdAdresse());
                    _callableStatement.setString("rue",technicien.getAdresse().getRue());
                    _callableStatement.setString("numero",technicien.getAdresse().getNumero());
                    _callableStatement.setInt("codePostalFK",technicien.getAdresse().getCodePostal().getIdCodePostal());
                    _callableStatement.setString("fonction",technicien.getFonction());                        
                    _callableStatement.setString("password",technicien.getPassword());
                    //_callableStatement.setInt("idRoles",technicien.getRole().getIdRole());
                    _callableStatement.setBoolean("gestionClient",technicien.getRole().getGestionClient());
                    _callableStatement.setBoolean("gestionDirection",technicien.getRole().getGestionDirection());
                    _callableStatement.setBoolean("gestionIntervention",technicien.getRole().getGestionIntervention());
                    _callableStatement.setBoolean("gestionOnSite",technicien.getRole().getGestionOnSite());
                    _callableStatement.setBoolean("gestionPlanning",technicien.getRole().getGestionPlanning());
                    _callableStatement.setBoolean("gestionSysteme",technicien.getRole().getGestionSysteme());
                    _callableStatement.setInt("zoneFK",technicien.getZone().getIdZone());
                
                    //execute
                    _callableStatement.executeUpdate();    

        } catch(SQLException e) {
            if (e.getMessage().equals("547")) {
                throw new TechnicienInexistantException("Code postal/Adresse/Role/Zone Incorrect",e);
            } else if (e.getMessage().equals("515")) {
                throw new TechnicienInexistantException("Non autorisé champs vide",e);
            } else if (e.getMessage().equals("50001")) {
                    throw new TechnicienInexistantException("L'employé n'existe pas",e);
            } else if (e.getMessage().equals("50002")) {
                    throw new TechnicienInexistantException("L'adresse n'a pas été trouvé",e);
            } else if (e.getMessage().equals("50003")) {
                    throw new TechnicienInexistantException("Le Rôles n'a pas été trouvé",e);
            } else if (e.getMessage().equals("50004")) {
                throw new TechnicienInexistantException("Un technicien doit avoir le droit gestionOnsite",e);
            } else  throw new TechnicienInexistantException(e);
        } catch(Exception e){
            throw new TechnicienInexistantException(e);
        } finally {
                if (_callableStatement != null) try { _callableStatement.close(); } catch(Exception e) {throw new TechnicienInexistantException(e);}
                _connection.deconnecter();
        }
    }    
    
    @Override
    public Vector<TechnicienDto> lister() throws TechnicienInexistantException {
        ResultSet resultat = null;
        RoleDto role = null;
        ZoneDto zoneTE = null;
        ZoneDto zone = null;
        CodePostalDto codePostal = null;
        AdresseDto adresse = null;
        TechnicienDto technicien = null;
            try {                                      
                //query
                _callableStatement = _connection.getConnection().prepareCall("{call sp_RHTechnicienList}");    
                //execute
                resultat = _callableStatement.executeQuery();
                
                Vector<TechnicienDto> liste = new Vector<TechnicienDto>();
                while (resultat.next()) {
                    role = new RoleDto( resultat.getInt("idRoles")
                                        ,resultat.getBoolean("gestionClient"),resultat.getBoolean("gestionDirection")
                                        ,resultat.getBoolean("gestionIntervention"), resultat.getBoolean("gestionOnSite")
                                        ,resultat.getBoolean("gestionPlanning"), resultat.getBoolean("gestionSysteme"));
                    zoneTE = new ZoneDto( resultat.getInt("idZoneTE"),
                                        resultat.getString("libZoneTE"));
                    zone = new ZoneDto( resultat.getInt("idZone"),
                                        resultat.getString("libZone"));
                    codePostal = new CodePostalDto( resultat.getInt("idCodePostal"),
                                                    resultat.getString("cp"),
                                                    resultat.getString("ville"),
                                                    resultat.getString("libPays"),
                                                    zone);
                    adresse = new AdresseDto(   resultat.getInt("idAdresse"),
                                                resultat.getString("rue"),
                                                resultat.getString("numero"),
                                                codePostal
                                                );
                    technicien = new TechnicienDto(  resultat.getInt("idRHMatricule")
                                                        ,resultat.getString("nom")
                                                        ,resultat.getString("prenom")
                                                        ,adresse
                                                        ,resultat.getString("telephone")
                                                        ,resultat.getString("email")
                                                        ,resultat.getString("fonction")
                                                        ,resultat.getString("password")
                                                        ,role, zoneTE);
                    
                    liste.add(technicien);
                }
                return liste;
            } catch(SQLException e) { 
                throw new TechnicienInexistantException(e);
            } finally { 
                if (resultat != null) try { resultat.close(); } catch(Exception e) { throw new TechnicienInexistantException(e);}
                if (_callableStatement != null) try { _callableStatement.close(); } catch(Exception e) {throw new TechnicienInexistantException(e);}
                    _connection.deconnecter();
            }
    }
    
    @Override
    public TechnicienDto identifier(int idRHMatricule,String password) throws TechnicienInexistantException {
        ResultSet resultat = null;
        RoleDto role = null;
        ZoneDto zoneTE = null;
        ZoneDto zone = null;
        CodePostalDto codePostal = null;
        AdresseDto adresse = null;
        TechnicienDto technicien = null;
            try {                                      
                //query
                _callableStatement = _connection.getConnection().prepareCall("{call sp_RHTechnicienIdentify(?,?)}");    
               //parameter
                _callableStatement.setInt("idRHMatricule",idRHMatricule);
                _callableStatement.setString("password",password);                
                //execute
                resultat = _callableStatement.executeQuery();
                
                if (resultat.next()) {
                    role = new RoleDto( resultat.getInt("idRoles")
                                        ,resultat.getBoolean("gestionClient"),resultat.getBoolean("gestionDirection")
                                        ,resultat.getBoolean("gestionIntervention"), resultat.getBoolean("gestionOnSite")
                                        ,resultat.getBoolean("gestionPlanning"), resultat.getBoolean("gestionSysteme"));
                    zoneTE = new ZoneDto( resultat.getInt("idZoneTE"),
                                        resultat.getString("libZoneTE"));
                    zone = new ZoneDto( resultat.getInt("idZone"),
                                        resultat.getString("libZone"));
                    codePostal = new CodePostalDto( resultat.getInt("idCodePostal"),
                                                    resultat.getString("cp"),
                                                    resultat.getString("ville"),
                                                    resultat.getString("libPays"),
                                                    zone);
                    adresse = new AdresseDto(   resultat.getInt("idAdresse"),
                                                resultat.getString("rue"),
                                                resultat.getString("numero"),
                                                codePostal
                                                );
                    technicien = new TechnicienDto(  resultat.getInt("idRHMatricule")
                                                        ,resultat.getString("nom")
                                                        ,resultat.getString("prenom")
                                                        ,adresse
                                                        ,resultat.getString("telephone")
                                                        ,resultat.getString("email")
                                                        ,resultat.getString("fonction")
                                                        ,resultat.getString("password")
                                                        ,role, zoneTE);
                }
                return technicien;
            } catch(SQLException e) { 
                throw new TechnicienInexistantException(e);
            } finally { 
                if (resultat != null) try { resultat.close(); } catch(Exception e) { throw new TechnicienInexistantException(e);}
                if (_callableStatement != null) try { _callableStatement.close(); } catch(Exception e) {throw new TechnicienInexistantException(e);}
                    _connection.deconnecter();
            }
    }
        /*
	@Override
	public TechnicienDto rechercher(String matricule) throws TechnicienInexistantException {
                ResultSet resultat = null;
                ZoneDto zone = null;
                AdresseDto adresse = null;
                RoleDto role = null;
                try {
                        //query
                        _callableStatement = _connection.getConnection().prepareCall("{call sp_TechnicienSelectMatricule(?)}");
                        //parameter
                        _callableStatement.setString("matricule",matricule);
                        //execute
                        resultat = _callableStatement.executeQuery();    
                	if(!resultat.next()) throw new TechnicienInexistantException();
			zone = new ZoneDto(resultat.getString("ZONE"));
                        adresse = new AdresseDto(   resultat.getString("RUE"),
                                                    resultat.getString("NUMERO"),
                                                    resultat.getString("CODEPOSTAL"),
                                                    resultat.getString("VILLE"),
                                                    resultat.getString("PAYS"),
                                                    zone);
                        role = new RoleDto(     resultat.getLong("IDROLE"),
                                                resultat.getBoolean("GESTIONCLIENT"),
                                                resultat.getBoolean("GESTIONINTERVENTION"),
                                                resultat.getBoolean("GESTIONPLANNING"),
                                                resultat.getBoolean("GESTIONDIRECTION"),
                                                resultat.getBoolean("GESTIONONSITE"),
                                                resultat.getBoolean("GESTIONSYSTEME")); 
                        return new TechnicienDto(   resultat.getString("MATRICULE"),
                                                    resultat.getString("NOM"),
                                                    resultat.getString("PRENOM"),
                                                    adresse,
                                                    resultat.getString("TELEPHONE"),
                                                    resultat.getString("EMAIL"),
                                                    role, 
                                                    resultat.getString("PASSWORD"));
		}catch(SQLException e){throw new TechnicienInexistantException(e);
                }finally{           
                        if (_callableStatement != null) try { _callableStatement.close(); } catch(Exception e) {}
                        _connection.deconnecter();}
	}

        @Override
        public Vector<TechnicienDto> rechercher(String nom, String prenom) throws TechnicienInexistantException {
		ResultSet resultat = null;
                ZoneDto zone = null;
                AdresseDto adresse = null;
                RoleDto role = null;
                TechnicienDto technicien = null;
                try {
                        //query
                        _callableStatement = _connection.getConnection().prepareCall("{call sp_TechnicienSelectNomPrenom(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}");
                        //parameter
                        _callableStatement.setString("nom",nom);
                        _callableStatement.setString("prenom",prenom);
                        //execute
                        resultat = _callableStatement.executeQuery();    
                	if(!resultat.next()) throw new TechnicienInexistantException();
			Vector<TechnicienDto> liste = new Vector<TechnicienDto>();
			while(resultat.next()){
                                zone = new ZoneDto(resultat.getString("ZONE"));
                                adresse = new AdresseDto(   resultat.getString("RUE"),
                                                            resultat.getString("NUMERO"),
                                                            resultat.getString("CODEPOSTAL"),
                                                            resultat.getString("VILLE"),
                                                            resultat.getString("PAYS"),
                                                            zone);
                                role = new RoleDto(     resultat.getLong("IDROLE"),
                                                        resultat.getBoolean("GESTIONCLIENT"),
                                                        resultat.getBoolean("GESTIONINTERVENTION"),
                                                        resultat.getBoolean("GESTIONPLANNING"),
                                                        resultat.getBoolean("GESTIONDIRECTION"),
                                                        resultat.getBoolean("GESTIONONSITE"),
                                                        resultat.getBoolean("GESTIONSYSTEME"));
                                technicien = new TechnicienDto( resultat.getString("MATRICULE"),
                                                                resultat.getString("NOM"),
                                                                resultat.getString("PRENOM"),
                                                                adresse,
                                                                resultat.getString("TELEPHONE"),
                                                                resultat.getString("EMAIL"),
                                                                role, 
                                                                resultat.getString("PASSWORD")); 
                                liste.add(technicien);}
                        return liste;
		}catch(SQLException e){throw new TechnicienInexistantException(e);
                }finally{           
                        if (_callableStatement != null) try { _callableStatement.close(); } catch(Exception e) {}
                        _connection.deconnecter();}
	}
       */                          
}